//Nguyen Trung Hieu
import java.util.Vector;

import javax.swing.undo.AbstractUndoableEdit;
import javax.swing.undo.CannotRedoException;
import javax.swing.undo.CannotUndoException;


public class UndoableToggleEdit extends AbstractUndoableEdit{
	
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	
	private TaskHandling.COMMAND_TYPE commandType;
	private Task beingConsideredTask;
	private TaskHandling beingConsideredTaskHandling;
	private int deleteTaskIndex; 
	private String newDesc;
	private String newTime;
	private String newDate;
	private String oldDesc;
	private String oldTime;
	private String oldDate;
	private TaskHandling destinationTaskHandling;
	private String[] taskIDArr;
	private Vector<Task> deletedTasks;
	private Vector<Integer> taskPositions;
	private boolean isIgnored;
	
	public UndoableToggleEdit (TaskHandling.COMMAND_TYPE commandType, Task beingConsideredTask, TaskHandling beingConsideredTaskHandling, int deleteTaskIndex, String newDesc, String newTime, String newDate, String oldDesc, String oldTime, String oldDate, TaskHandling destinationTaskHandling, String[] taskIDArr, Vector<Task> deletedTasks, Vector<Integer> taskPositions){
		this.beingConsideredTask = beingConsideredTask;
		this.commandType = commandType;
		this.beingConsideredTaskHandling = beingConsideredTaskHandling;
		this.deleteTaskIndex = deleteTaskIndex;
		this.newDesc = newDesc;
		this.newTime = newTime;
		this.newDate = newDate;
		this.oldDesc = oldDesc;
		this.oldTime = oldTime;
		this.oldDate = oldDate;
		this.destinationTaskHandling = destinationTaskHandling;
		this.taskIDArr = taskIDArr;
		this.deletedTasks = deletedTasks;
		this.taskPositions = taskPositions;
		
		try{
		if (beingConsideredTask.getIsOverDue().searchByTaskID(beingConsideredTask.getID()) != -1){
			isIgnored = true;
		}
		else {isIgnored = false;
		}
		}catch (NullPointerException nPE){
			isIgnored = false;
		}
	}
	
	public String getPresentationName(){
		if (commandType == TaskHandling.COMMAND_TYPE.mark) {
			return "mark as done";
		}else if (commandType == TaskHandling.COMMAND_TYPE.mulmark) {
			return "multiple mark as done";
		}	else if (commandType == TaskHandling.COMMAND_TYPE.muldel) {
			return "multiple delete";
		}else 	return commandType.toString();
	}
	
	public String toString(){
		return beingConsideredTask.getID();	
	}

	public void undo() throws CannotUndoException {
		super.undo();
		if (!isIgnored){
		if (commandType == TaskHandling.COMMAND_TYPE.add) {
				beingConsideredTaskHandling.deleteAndReturnTask(
						beingConsideredTask.getID(), true);
			} 
			else if (commandType == TaskHandling.COMMAND_TYPE.delete) {
				beingConsideredTaskHandling.addTask(beingConsideredTask,
						deleteTaskIndex, true);

			}
			else if (commandType == TaskHandling.COMMAND_TYPE.edit) {
				beingConsideredTaskHandling.editTask(oldDesc, oldTime, oldDate, beingConsideredTask.getID(), true);

			}
			else if (commandType == TaskHandling.COMMAND_TYPE.mark) {
				destinationTaskHandling.markAsDone(beingConsideredTask.getID(), beingConsideredTaskHandling, beingConsideredTask.getOldPosition(), true);
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.mulmark) {
				for (int i = taskIDArr.length - 1; i > -1; i--){
					destinationTaskHandling.markAsDone(taskIDArr[i],beingConsideredTaskHandling, taskPositions.get(i), true);
				}
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.muldel) {
				for (int i = deletedTasks.size() - 1; i > -1; i--){
					beingConsideredTaskHandling.addTask(deletedTasks.get(i), taskPositions.get(i), true);
				}
			}
		}
	}
	
	
	public void redo() throws CannotRedoException {
		super.redo();
		
		if (!isIgnored){

			if (commandType == TaskHandling.COMMAND_TYPE.add) {
				beingConsideredTaskHandling.addTask(beingConsideredTask,
						deleteTaskIndex, true);
				
			} else if (commandType == TaskHandling.COMMAND_TYPE.delete) {
				beingConsideredTaskHandling.deleteAndReturnTask(
						beingConsideredTask.getID(), true);
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.edit) {
				beingConsideredTaskHandling.editTask(newDesc, newTime, newDate, beingConsideredTask.getID(), true);
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.mark) {
				beingConsideredTaskHandling.markAsDone(beingConsideredTask.getID(), destinationTaskHandling, -1, true);
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.mulmark) {
				beingConsideredTaskHandling.multipleMarkAsDone(taskIDArr, destinationTaskHandling, true);
			}
			else if (commandType == TaskHandling.COMMAND_TYPE.muldel) {
				beingConsideredTaskHandling.multipleDelete(taskIDArr, true);
			}
		}
	}
}
	
	
